//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <winhack.h>
#include <elasysapi.h>
#include <gsensor.h>
#include <stdio.h>
#include <framebuffer.h>
#include <eventman.h>

HANDLE g_hGsensorLock;
static Int32 s_iState = GSENSOR_NONE_INTERRUPT;
EXTERN void VideoGsensorUp();
EXTERN void VideoGsensorDown();
EXTERN void VideoGsensorRight();
EXTERN void VideoGsensorLeft();

typedef void (*COORDINATE)(int x, int y, int *px, int *py);
EXTERN COORDINATE g_Coordinate;
extern void CoordinateUp(int x, int y, int *px, int *py);
EXTERN void CoordinateDown(int x, int y, int *px, int *py);
EXTERN void CoordinateRight(int x, int y, int *px, int *py);
EXTERN void CoordinateLeft(int x, int y, int *px, int *py);

CGSensor::~CGSensor()
{
    if(NULL != g_hGsensorLock){
        CloseHandle(g_hGsensorLock);
    }
    return;
}


ECode CGSensor::Read(
    /* [in] */ Int64 offset,
    /* [in] */ Int32 bytesToRead,
    /* [out] */ MemoryBuf * pBuffer,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    return E_NOT_IMPLEMENTED;
}

ECode CGSensor::Write(
    /* [in] */ Int64 offset,
    /* [in] */ const MemoryBuf & buffer,
    /* [out] */ Int32 * pBytesWritten,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    // TODO;
    return E_NOT_IMPLEMENTED;
}

ECode CGSensor::Control(
    /* [in] */ Handle32 controlCode,
    /* [in] */ const MemoryBuf & inBuffer,
    /* [out] */ MemoryBuf * pOutBuffer,
    /* [out] */ IEvent * * ppCompletionEvent)
{
    ECode ec = NOERROR;
    switch (controlCode) {
        case 2:{//Get GSensor state
            Int32 *pBuf = NULL;
            assert(NULL != (char *)pOutBuffer);
            pBuf = (Int32 *)((Byte *)pOutBuffer->GetPayload());
            assert(NULL != pBuf);
            *pBuf = s_iState;
            pOutBuffer->SetUsed(sizeof(Int32));
            break;
        }
        default:
            //ec = E_NOT_IMPLEMENTED
            break;
    }

    return ec;
}

void GSensorGetEvent(char key)
{
    Int32 iEvent = 0;
    MemoryBuf eventData ((Byte *)&iEvent, sizeof(Int32));
    //Get the simulator event

    WaitForSingleObject(g_hGsensorLock, (DWORD)INFINITE);
    switch(key){
        case 0x25://left arrow
            iEvent = GSENSOR_ROTATE_LEFT_INTERRUPT;
            VideoGsensorLeft();
            g_Coordinate = CoordinateLeft;
            break;
        case 0x26://up arrow
            iEvent = GSENSOR_ROTATE_UP_INTERRUPT;
            VideoGsensorUp();
            g_Coordinate = CoordinateUp;
            break;
        case 0x28://down arrow
            iEvent = GSENSOR_ROTATE_DOWN_INTERRUPT;
            VideoGsensorDown();
            g_Coordinate = CoordinateDown;
            break;
        case 0x27://right arrow
            iEvent = GSENSOR_ROTATE_RIGHT_INTERRUPT;
            VideoGsensorRight();
            g_Coordinate = CoordinateRight;
            break;
        case 0x55://u
            iEvent = GSENSOR_ROTATE_TOP_INTERRUPT;
            break;
        case 0x49://i
            iEvent = GSENSOR_ROTATE_BOTTOM_INTERRUPT;
            break;
        case 0x4e://n
            iEvent = GSENSOR_DOUBLE_TAP_INTERRUPT;
            break;
        case 0x4d://m
            iEvent = GSENSOR_SINGLE_TAP_INTERRUPT;
            break;
        case 0x4f://o
            iEvent = GSENSOR_SHAKE_INTERRUPT;
            break;
        default:
            ReleaseMutex(g_hGsensorLock);
            return;
    }
    s_iState = iEvent;
    ReleaseMutex(g_hGsensorLock);
    //change the frambuffer

    EmPostEvent(230, eventData);
}



EXTERN IDeviceDriver * CDECL CreateGsensor(uint_t uDeviceNo, void *pvParameter)
{
    ECode ec;
    CGSensor *pGSensor = new CGSensor;
    if(NULL == pGSensor){
        return NULL;
    }
    pGSensor->AddRef();
    ec = _CSystem_RegisterRunningObject(GSENSOR_DEVICE_NAME, (PInterface)pGSensor);
    if(FAILED(ec)){
        printf("Err: Failed register GSensor driver\n");
        pGSensor->Release();
        return NULL;
    }

    g_hGsensorLock = CreateMutexW(NULL, FALSE, NULL);
    if(NULL == g_hGsensorLock){
        printf("Error: gsensor lock create failed! \
        file:%s. line:%d. \n",
        __FILE__, __LINE__);
        _CSystem_UnregisterRunningObject(GSENSOR_DEVICE_NAME);
        pGSensor->Release();
        return FALSE;
    }


    return (IDeviceDriver *)pGSensor;
}
